﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using HYCodeBase.WinForm;

namespace YRevitJig
{
	public class WndMsgManager : IDisposable
	{
		public WndMsgManager(UIDocument uiDoc)
		{
			this.m_uiDoc = uiDoc;
			this.InitWndHandle();
			this.InitHook2RevitWndHandle(true);
			this.InitJigForm(true);
			this.UpdateXJigFormSize2MDIActiveClientWnd();
			this.SetFocus2MDIActiveChildClient();
		}

		public void Dispose()
		{
			this.InitHook2RevitWndHandle(false);
			this.InitJigForm(false);
		}

		private void InitJigForm(bool bInit)
		{
			bool flag = !bInit;
			if (flag)
			{
				bool flag2 = WndMsgManager.m_jigForm != null && !WndMsgManager.m_jigForm.IsDisposed;
				if (flag2)
				{
					this.JigPen.Dispose();
					using (Graphics graphics = WndMsgManager.m_jigForm.CreateGraphics())
					{
						graphics.Clear(WndMsgManager.m_jigForm.BackColor);
					}
				}
			}
			else
			{
				Process currentProcess = Process.GetCurrentProcess();
				WindowHandle owner = new WindowHandle(currentProcess.MainWindowHandle);
				bool flag3 = WndMsgManager.m_jigForm == null;
				if (flag3)
				{
					WndMsgManager.m_jigForm = new JigTransparentForm();
					WndMsgManager.m_jigForm.Show(owner);
				}
				this.JigPen = new Pen(this.RevitViewBackgroundReverseColor);
			}
		}

		private void UpdateXJigFormSize2MDIActiveClientWnd()
		{
			DllImportManeger.Rect rect;
			DllImportManeger.GetWindowRect(this.m_hMDIClientWnd, out rect);
            System.Drawing.Point point = new System.Drawing.Point(rect.left, rect.top);
			DllImportManeger.Rect rect2;
			DllImportManeger.GetWindowRect(this.m_hMDIActiveChildClientWnd, out rect2);
            System.Drawing.Point point2 = new System.Drawing.Point(rect2.left, rect2.top);
			int num = (rect.left > rect2.left) ? rect.left : rect2.left;
			int num2 = (rect.top > rect2.top) ? rect.top : rect2.top;
			int num3 = (rect.right < rect2.right) ? rect.right : rect2.right;
			int num4 = (rect.bottom < rect2.bottom) ? rect.bottom : rect2.bottom;
            WndMsgManager.m_jigForm.Location = new System.Drawing.Point(num, num2);
			Size size = new Size(num3 - num, num4 - num2);
			WndMsgManager.m_jigForm.Size = size;
		}

		private void DispatchEventOnMouseMove(IntPtr wParam, IntPtr lParam)
		{
			bool flag = this.OnMouseActivity != null;
			if (flag)
			{
                System.Drawing.Point position = Cursor.Position;
				DllImportManeger.ScreenToClient(WndMsgManager.m_jigForm.Handle, ref position);
				MouseEventArgs e = new MouseEventArgs(MouseButtons.None, 0, position.X, position.Y, 0);
				this.OnMouseActivity(this, e);
			}
		}

		private void DispatchEventOnDraw(IntPtr wParam, IntPtr lParam)
		{
			bool flag = this.OnPaintEvent != null;
			if (flag)
			{
				Graphics graphics = WndMsgManager.m_jigForm.CreateGraphics();
				graphics.Clear(this.JigForm.BackColor);
				try
				{
                    System.Drawing.Rectangle clipRect = new System.Drawing.Rectangle(0, 0, WndMsgManager.m_jigForm.Width, WndMsgManager.m_jigForm.Height);
					PaintEventArgs e = new PaintEventArgs(graphics, clipRect);
					this.OnPaintEvent(this, e);
				}
				catch
				{
				}
				finally
				{
					graphics.Dispose();
				}
			}
		}

		private bool InitWndHandle()
		{
			this.m_hMDIClientWnd = DllImportManeger.FindWindowEx(Process.GetCurrentProcess().MainWindowHandle, IntPtr.Zero, "MDIClient", "");
			bool flag = this.m_hMDIClientWnd == IntPtr.Zero;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				this.m_hMDIActiveChildWnd = (IntPtr)DllImportManeger.SendMessage(this.m_hMDIClientWnd, 553, IntPtr.Zero, IntPtr.Zero);
				bool flag2 = this.m_hMDIActiveChildWnd == IntPtr.Zero;
				if (flag2)
				{
					result = false;
				}
				else
				{
					IntPtr intPtr = IntPtr.Zero;
					try
					{
						intPtr = Marshal.StringToHGlobalAnsi("AfxFrameOrView");
						DllImportManeger.EnumChildWindows(this.m_hMDIActiveChildWnd, new DllImportManeger.CallBack(this.EnumMDIChildClient), intPtr);
					}
					catch
					{
						return false;
					}
					finally
					{
						Marshal.FreeHGlobal(intPtr);
					}
					result = true;
				}
			}
			return result;
		}

		private bool EnumMDIChildClient(IntPtr hwnd, IntPtr ptrKey)
		{
			try
			{
				string value = Marshal.PtrToStringAnsi(ptrKey);
				StringBuilder stringBuilder = new StringBuilder(512);
				DllImportManeger.GetClassName(hwnd, stringBuilder, stringBuilder.Capacity);
				bool flag = stringBuilder.ToString().Contains(value);
				if (flag)
				{
					this.m_hMDIActiveChildClientWnd = hwnd;
					return false;
				}
			}
			catch
			{
			}
			return true;
		}

		private bool InitHook2RevitWndHandle(bool bAttach)
		{
			if (bAttach)
			{
				this.m_hMDIClientWndProc = new DllImportManeger.NewWndProc(this.MDIClientWndMsgProc);
				this.m_hMDIClientWndProcOld = DllImportManeger.SetWindowLong(this.m_hMDIClientWnd, -4, this.m_hMDIClientWndProc);
				this.m_hMDIActiveChildWndProc = new DllImportManeger.NewWndProc(this.MDIActiveChildClientWndMsgProc);
				this.m_hMDIActiveChildWndProcOld = DllImportManeger.SetWindowLong(this.m_hMDIActiveChildClientWnd, -4, this.m_hMDIActiveChildWndProc);
			}
			else
			{
				bool flag = this.m_hMDIClientWndProc != null;
				if (flag)
				{
					DllImportManeger.SetWindowLong(this.m_hMDIClientWnd, -4, this.m_hMDIClientWndProcOld);
					this.m_hMDIClientWndProc = null;
				}
				bool flag2 = this.m_hMDIActiveChildWndProc != null;
				if (flag2)
				{
					DllImportManeger.SetWindowLong(this.m_hMDIActiveChildClientWnd, -4, this.m_hMDIActiveChildWndProcOld);
					this.m_hMDIActiveChildWndProc = null;
				}
			}
			return true;
		}

		private IntPtr MDIClientWndMsgProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
		{
			IntPtr result = DllImportManeger.CallWindowProc(this.m_hMDIClientWndProcOld, hWnd, msg, wParam, lParam);
			if (msg != 32)
			{
				if (msg - 70 <= 1 || msg == 546)
				{
					this.UpdateXJigFormSize2MDIActiveClientWnd();
				}
			}
			else
			{
				short num = JigFuncs.HIWORD((int)lParam);
				bool flag = num == 512;
				if (flag)
				{
					bool flag2 = this.m_UserForm != null && !this.m_UserForm.IsDisposed;
					if (flag2)
					{
                        System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(this.m_UserForm.Location, this.m_UserForm.Size);
						bool flag3 = !rectangle.Contains(Cursor.Position);
						if (flag3)
						{
							bool flag4 = !this.m_bMouseOutOfUserFormClient && this.OnMouseLeaveFormClientEvent != null;
							if (flag4)
							{
								EventArgs e = new EventArgs();
								this.OnMouseLeaveFormClientEvent(this, e);
								DllImportManeger.SetCapture(this.m_hMDIActiveChildClientWnd);
								DllImportManeger.SetFocus(this.m_hMDIActiveChildClientWnd);
							}
							this.m_bMouseOutOfUserFormClient = true;
						}
					}
				}
			}
			return result;
		}

		private IntPtr MDIActiveChildClientWndMsgProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
		{
			IntPtr result = DllImportManeger.CallWindowProc(this.m_hMDIActiveChildWndProcOld, hWnd, msg, wParam, lParam);
			if (msg <= 15)
			{
				switch (msg)
				{
				case 5:
					break;
				case 6:
					return result;
				case 7:
				{
					bool flag = this.OnFocusEvent != null;
					if (flag)
					{
						this.OnFocusEvent(this, true);
					}
					return result;
				}
				case 8:
				{
					bool flag2 = this.OnFocusEvent != null;
					if (flag2)
					{
						this.OnFocusEvent(this, false);
					}
					return result;
				}
				default:
					if (msg != 15)
					{
						return result;
					}
					this.DispatchEventOnDraw(wParam, lParam);
					return result;
				}
			}
			else if (msg != 71)
			{
				if (msg == 256)
				{
					bool flag3 = this.OnKeyDownEvent != null;
					if (flag3)
					{
						KeyEventArgs e = new KeyEventArgs((Keys)((int)wParam));
						this.OnKeyDownEvent(this, e);
					}
					return result;
				}
				if (msg != 512)
				{
					return result;
				}
				bool flag4 = this.m_UserForm != null && !this.m_UserForm.IsDisposed;
				if (flag4)
				{
                    System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(this.m_UserForm.Location, this.m_UserForm.Size);
					bool flag5 = rectangle.Contains(Cursor.Position);
					if (flag5)
					{
						bool flag6 = this.m_bMouseOutOfUserFormClient && this.OnMouseMoveIntoFormClientEvent != null;
						if (flag6)
						{
							EventArgs e2 = new EventArgs();
							this.OnMouseMoveIntoFormClientEvent(this, e2);
							DllImportManeger.ReleaseCapture();
							DllImportManeger.SetFocus(this.m_UserForm.Handle);
						}
						this.m_bMouseOutOfUserFormClient = false;
						return result;
					}
				}
				this.DispatchEventOnMouseMove(wParam, lParam);
				this.DispatchEventOnDraw(wParam, lParam);
				return result;
			}
			this.UpdateXJigFormSize2MDIActiveClientWnd();
			return result;
		}

		public int SetFocus2MDIActiveChildClient()
		{
			return DllImportManeger.SendMessage(this.m_hMDIActiveChildWnd, 7, IntPtr.Zero, IntPtr.Zero);
		}

		private bool DrawJigFormBondary()
		{
			Graphics graphics = null;
			Font font = null;
			SolidBrush solidBrush = null;
			Pen pen = null;
			try
			{
				graphics = WndMsgManager.m_jigForm.CreateGraphics();
				graphics.Clear(WndMsgManager.m_jigForm.BackColor);
                System.Drawing.Color red = System.Drawing.Color.Red;
                System.Drawing.Point p = Cursor.Position;
				string s = string.Format("屏幕坐标：({0}, {1})", p.X, p.Y);
				p = WndMsgManager.m_jigForm.PointToClient(p);
				font = new Font("宋体", 12f);
				solidBrush = new SolidBrush(red);
				graphics.DrawString(s, font, solidBrush, p);
                List<System.Drawing.Point> list = new List<System.Drawing.Point>(5);
                System.Drawing.Point item = new System.Drawing.Point(0, 0);
                System.Drawing.Point item2 = new System.Drawing.Point(WndMsgManager.m_jigForm.ClientSize.Width, 0);
                System.Drawing.Point item3 = new System.Drawing.Point(0, WndMsgManager.m_jigForm.ClientSize.Height);
                System.Drawing.Point item4 = new System.Drawing.Point(WndMsgManager.m_jigForm.ClientSize.Width, WndMsgManager.m_jigForm.ClientSize.Height);
				list.Add(item);
				list.Add(item2);
				list.Add(item4);
				list.Add(item3);
				list.Add(item);
				pen = new Pen(red, 10f);
				graphics.DrawLines(pen, list.ToArray());
			}
			catch
			{
				return false;
			}
			finally
			{
				font.Dispose();
				pen.Dispose();
				solidBrush.Dispose();
				graphics.Dispose();
			}
			return true;
		}

		public Graphics CreateJigFormGraphics()
		{
			return WndMsgManager.m_jigForm.CreateGraphics();
		}

		public UIDocument UiDoc
		{
			get
			{
				return this.m_uiDoc;
			}
		}

		public Document Doc
		{
			get
			{
				return this.UiDoc.Document;
			}
		}

		public UIView UiViewActive
		{
			get
			{
				try
				{
					IList<UIView> openUIViews = this.m_uiDoc.GetOpenUIViews();
					return openUIViews.First((UIView view) => view.ViewId == this.m_uiDoc.ActiveView.Id);
				}
				catch
				{
				}
				return null;
			}
		}

        public Autodesk.Revit.DB.View ViewActive
		{
			get
			{
				return this.UiDoc.ActiveView;
			}
		}

		public SketchPlane SketchPlane
		{
			get
			{
				try
				{
					return this.ViewActive.SketchPlane;
				}
				catch
				{
				}
				return null;
			}
		}

		protected Pen JigPen { get; private set; }

        protected System.Windows.Forms.Form JigForm
		{
			get
			{
				return WndMsgManager.m_jigForm;
			}
		}

        protected System.Drawing.Color RevitViewBackgroundReverseColor
		{
			get
			{
				return RevitVersionFuncs.GetViewBackgroundReverseColor(this.m_uiDoc.Application.Application);
			}
		}

		public event MouseEventHandler OnMouseActivity;

		protected UIDocument m_uiDoc;

		private static JigTransparentForm m_jigForm;

        protected System.Windows.Forms.Form m_UserForm;

		private DllImportManeger.NewWndProc m_hMDIClientWndProc = null;

		private IntPtr m_hMDIClientWndProcOld = IntPtr.Zero;

		private DllImportManeger.NewWndProc m_hMDIActiveChildWndProc = null;

		private IntPtr m_hMDIActiveChildWndProcOld = IntPtr.Zero;

		protected IntPtr m_hMDIClientWnd = IntPtr.Zero;

		protected IntPtr m_hMDIActiveChildWnd = IntPtr.Zero;

		protected IntPtr m_hMDIActiveChildClientWnd = IntPtr.Zero;

		public PaintEventHandler OnPaintEvent;

		public KeyEventHandler OnKeyDownEvent;

		public WndMsgManager.FocusChangeEvent OnFocusEvent;

		public WndMsgManager.MouseLeaveFormClientEvnetHandler OnMouseLeaveFormClientEvent;

		private bool m_bMouseOutOfUserFormClient = true;

		public WndMsgManager.MouseMoveIntoFormClientEvnetHandler OnMouseMoveIntoFormClientEvent;

		public delegate void FocusChangeEvent(object sender, bool bHadFocus);

		public delegate void MouseLeaveFormClientEvnetHandler(object sender, EventArgs e);

		public delegate void MouseMoveIntoFormClientEvnetHandler(object sender, EventArgs e);
	}
}
